//
// Created by wujehy on 2020/8/23.
//


#include <Common.h>
#include "UserDB.h"
#include "crud_tools.h"

void UserDB::init()
{
    int ret = creatTable();
    gDebug <<" ret = " <<ret ;
}


int UserDB::creatTable()
{
    std::string createSql = "CREATE TABLE `" + m_table_name + "` ("
                                                              "  `username` TEXT NULL," ///<string
                                                              "  `password` TEXT NULL," ///<string
                                                              "  `Createat` integer NULL," ///<string
                                                              "  `ModifyAt` integer NULL," ///<string
                                                              "  PRIMARY KEY (username)"
                                                              ");";
    std::string indexSql = "CREATE INDEX `" + m_table_name + "_idx` ON `" + m_table_name + "` ( `username` );";
    return db_createTablefunc(this->m_database, m_table_name, createSql, indexSql);
}

UserDB::UserDB(SQLite::Database *mDatabase) : m_database(mDatabase)
{

}


int UserDB::add(const std::string &username, const std::string &password)
{
    std::string exist_sql = "select COUNT(*) from `" + m_table_name + "` where `username` = ? ;";
    BindCallbackFunction exist_bind_func = [&](SQLite::Statement &query, void *userdata)
    {
        query.bind(1, username);
    };
    int64_t currentTime = Common::getTimeMilli();
    std::string addSql = "INSERT INTO `" + m_table_name +
                         "` ("
                         "`username`, "
                         "`password`, "
                         "`Createat`, "
                         "`ModifyAt`"
                         ") VALUES ( ?,?,?,?);";
    BindCallbackFunction add_bind_func = [&](SQLite::Statement &query, void *userdata)
    {
        query.bind(1, username);
        query.bind(2, password);
        query.bind(3, currentTime);
        query.bind(4, currentTime);
    };
    DataExistCallbackFunction existCallback = [&]()
    {
        // TODO 存在更新
        this->update(username, password);
        return EXIT_SUCCESS;
    };
    LOGINFO << "====addsql: " << addSql;
    return db_add_func(m_database, m_table_name, exist_sql, exist_bind_func, addSql, add_bind_func, existCallback);

}

int UserDB::update(const std::string &username, const std::string &password)
{
    std::string updateSql = "update `" + m_table_name + "` set `password` = ? , `ModifyAt` = ?  where `username` = ? ";
    int64_t currentTime = Common::getTimeMilli();
    BindCallbackFunction updata_func = [&](SQLite::Statement &query, void *userdata)
    {
        query.bind(1, password);
        query.bind(2, currentTime);
        query.bind(3, username);
    };

    return db_update_func(m_database, m_table_name, updateSql, updata_func);
}

int UserDB::del(const std::string &username)
{

    std::string delSql = delSql = "DELETE FROM " + m_table_name + " WHERE `username` = ? ;";
    BindCallbackFunction delete_func = [&](SQLite::Statement &query, void *userdata)
    {
        query.bind(1, username);
    };

    int size = db_del_func(m_database, m_table_name, delSql, delete_func);
    LOGINFO << "delete size = " << size;
}

bool UserDB::exist(const std::string &username, const std::string &password)
{
    std::string value;
//    find_sql_ss << "select * from " << m_table_name;
    std::string find_sql = "select * from " + m_table_name + " where `username` = ? and `password` = ? ;";

    BindCallbackFunction find_func = [&](SQLite::Statement &query, void *userdata)
    {
        query.bind(1, username);
        query.bind(2, password);
    };


    ForechoCallbackFunction forechoCallbackFunction = [&](SQLite::Statement &query)
    {
        value = query.getColumn("password").getString();

        return false;
    };

    int ret = db_find_func(m_database, m_table_name, find_sql, find_func, forechoCallbackFunction);

    LOGINFO << " ret = " << ret;

    return value == password;
}

int UserDB::getPassword(const std::string &username, std::string &password )
{
//    find_sql_ss << "select * from " << m_table_name;
    std::string find_sql = "select * from " + m_table_name + " where `username` = ?   ;";

    BindCallbackFunction find_func = [&](SQLite::Statement &query, void *userdata)
    {
        query.bind(1, username);
    };


    ForechoCallbackFunction forechoCallbackFunction = [&](SQLite::Statement &query)
    {
        password = query.getColumn("password").getString();

        return false;
    };

    int ret = db_find_func(m_database, m_table_name, find_sql, find_func, forechoCallbackFunction);

    LOGINFO << " ret = " << ret;

    return ret ;
}
